package com.ruoyi.law.factory.inter.impl;

import cn.hutool.core.map.MapUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.law.annotation.ReturnStrategy;
import com.ruoyi.law.enums.ReturnStrategyEnum;
import com.ruoyi.law.factory.inter.DataHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 一定时间内只能执行指定次数
 *
 * @author lie
 * @date 2023/11/15
 */
@ReturnStrategy(returnStrategy = ReturnStrategyEnum.RATE_LIMITING)
@Service
public class RateLimitStrategyHandler implements DataHandler {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public Object handleData(Map<String, Object> params) {
        String message = MapUtil.getStr(params, "message");
        String key = MapUtil.getStr(params, "key");
        Object value = MapUtil.get(params, "value", Object.class);
        int limit = MapUtil.getInt(params, "limit");
        long timeout = MapUtil.getLong(params, "timeout");
        boolean isAllowed = isAllowed(key, value, limit, timeout);
        if (!isAllowed) {
            throw new ServiceException(message);
        }
        return null;
    }

    private boolean isAllowed(String key, Object value, int limit, long timeout) {
        int requestCount = (value instanceof Integer) ? (Integer) value : 1;

        if (requestCount >= limit) {
            return false;
        }

        requestCount++;
        redisTemplate.opsForValue().set(key, requestCount, timeout, TimeUnit.SECONDS);

        return true;
    }
}
